<?php

namespace App\Admin\Form;

use App\Admin\Form;
use Illuminate\Support\Collection;

class Tab
{
    /**
     * 该选项卡属于的表单实例
     *
     * @var Form
     */
    protected $form;

    /**
     * 所有选项卡
     *
     * @var Collection
     */
    protected $tabs;

    /**
     * 每个选项卡,需要从form的各组件中分割组件的起始偏移量
     *
     * @var int
     */
    protected $offset = 0;

    /**
     * Tab constructor.
     * @param Form $form
     */
    public function __construct(Form $form)
    {
        $this->form = $form;

        $this->tabs = new Collection();
    }

    /**
     * 添加一个选项卡,并设置内容
     *
     * @param string $title
     * @param \Closure $content
     * @param bool $active
     * @return $this
     */
    public function append($title, \Closure $content, $active = false)
    {
        $fields = $this->collectFields($content);

        if ($fields->isEmpty()) {
            return $this;
        }

        $id = 'form-' . ($this->tabs->count() + 1);

        $this->tabs->push(compact('id', 'title', 'fields', 'active'));

        return $this;
    }

    /**
     * 获取该选项卡下的各字段(表单组件)
     *
     * @param \Closure $content
     * @return Collection
     */
    protected function collectFields(\Closure $content)
    {
        call_user_func($content, $this->form);

        // 获得截止到当前选项卡,已推入form中的所有组件
        $all = $this->form->builder()->fields();

        // 获取该选项卡的分割的组件
        $fields = $all->slice($this->offset);

        // 设定下一个选项卡需要分割的起始偏移量
        $this->offset = $all->count();

        return $fields;
    }

    /**
     * 获取所有选项卡
     *
     * @return Collection
     */
    public function getTabs()
    {
        if ($this->tabs->filter(function ($tab) {
            return $tab['active'];
        })->isEmpty()) {
            $first = $this->tabs->first();
            $first['active'] = true;

            $this->tabs->offsetSet(0, $first);
        }

        return $this->tabs;
    }

    /**
     * 判断是否没有选项卡
     *
     * @return bool
     */
    public function isEmpty()
    {
        return $this->tabs->isEmpty();
    }
}